package team.lhc.cms.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import team.lhc.cms.entity.Visitor;
import team.lhc.cms.mapper.VisitorMapper;
import team.lhc.cms.service.VisitorService;
import team.lhc.cms.util.JsonResult;
import team.lhc.cms.util.PassCode;
import team.lhc.cms.util.RedisUtil;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 文
 * @description 访客service层实现类
 */
@Slf4j
@Service
public class VisitorServiceImpl implements VisitorService {
    @Autowired
    VisitorMapper visitorMapper;

    @Autowired
    RedisUtil redisUtil;

    /**
     * 创建申请
     * @author 文
     * @param visitor
     * @return
     */
    @Override
    public Map<String,Object> apply(Visitor visitor,String token) throws ParseException {
        //判断申请时间是否合法
        Integer timeDifference = timeDifference(visitor.getVisitTime(), today());
        Map<String,Object> map = new HashMap<>();
        if (timeDifference < 0){
            map.put("passCode","0");
            return map;
        }
        Map<String,Object> data = (Map<String, Object>) redisUtil.hget(token);
        visitor.setUid((Integer) data.get("uid"));
        //创建uuid并保存
        visitor.setUuid(PassCode.createPassCode());
        visitorMapper.save(visitor);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-MM-dd");
        Date today = simpleDateFormat.parse(today());
        Date applyTime = simpleDateFormat.parse(visitor.getVisitTime());
        //若申请日期为今天，则二维码立即生效
        if (today.equals(applyTime)){
            //获取剩下的时间,用于设置过期时间
            Date tomorrow = simpleDateFormat.parse(simpleDateFormat.format(new Date(today.getTime() + 1000 * 60 * 60 * 24 * 1 * visitor.getDays())));
            Date now = new Date();
            long diff = tomorrow.getTime() - now.getTime();
            redisUtil.set(visitor.getUuid(),visitor.getVisitorTel(),diff);
            //若有临时车牌则加到redis中
            if (visitor.getTempLicense() != null){
                redisUtil.hset("tempLicense",visitor.getTempLicense(),visitor.getRoomId(),diff);
            }
        }
        //创建失败
        if (visitor.getVisitId() == null){
            map.put("passCode","0");
            return map;
        }
        map.put("passCode",visitor);
        //输出日志作分析([visitor][uid][num][time][interval])
        log.info("[visitor][" + visitor.getVisitorNumber() + "][" + simpleDateFormat.format(applyTime) + "][" + timeDifference + "]");
        return map;
    }

    /**
     * 验证通行码
     * @author 文
     * @param passCode
     * @param tel
     * @return
     */
    @Override
    public String verification(String passCode, String tel) {
        Boolean hasKey = redisUtil.hasKey(passCode);
        if (Boolean.TRUE.equals(hasKey)){
            return redisUtil.get(passCode).equals(tel)?JsonResult.success("可通行"):JsonResult.failed("手机号有误,不可通行");
        }
        return JsonResult.failed("此通行码未到申请日期或已过期,不可通行");
    }

    /**
     * 获取申请的获取记录
     * @author 文
     * @param token
     * @return
     */
    @Override
    public List<Visitor> getRecordList(String token) {
        Map<String,Object> data = (Map<String, Object>) redisUtil.hget(token);
        return visitorMapper.getListByUid(data.get("uid"));
    }

    /**
     * 查询某条记录
     * @author 文
     * @param token
     * @param visitId
     * @return
     */
    @Override
    public String getRecord(String token, String visitId) {
        Map<String,Object> data = (Map<String, Object>) redisUtil.hget(token);
        Visitor visitor = visitorMapper.findByVisitId(visitId);
        //判断是否有该记录
        if (visitor != null){
            //判断是否属于自己的记录
            if (visitor.equals(data.get("uid"))){
                Map<String,Object> map = new HashMap<>();
                map.put("data",visitor);
                return JsonResult.success(map);
            }else {
                return JsonResult.failed("无权限查看此条记录");
            }
        }else {
            return JsonResult.failed("找不到该记录");
        }

    }

    /**
     * 使当天的通行码生效(深夜12点时工作)
     * @author 文
     * @throws ParseException
     */
    @Scheduled(cron = "0 0 0 * * ? ")
    private void effectiveCode() throws ParseException {
        String today = today();
        List<Visitor> effective = visitorMapper.getListByDate(today);
        for (Visitor visitor : effective) {
            redisUtil.set(visitor.getUuid(), visitor.getVisitorTel(), visitor.getDays() * 86400000L);
            //设置临时车牌
            if (visitor.getTempLicense() != null){
                redisUtil.hset("tempLicense",visitor.getTempLicense(),visitor.getRoomId(),visitor.getDays() * 86400000L);
            }
        }
    }

    /**
     * 获取今天日期
     * @author 文
     * @return 返回以"yyyy-MM-dd"为格式的今日日期
     * @throws ParseException
     */
    private String today(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return simpleDateFormat.format(new Date());
    }

    /**
     * 计算时间差(天)
     * @author 文
     * @param newDate
     * @param oldDate
     * @return
     * @throws ParseException
     */
    private Integer timeDifference(String newDate, String oldDate) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-MM-dd");
        Date d1 = simpleDateFormat.parse(newDate);
        Date d2 = simpleDateFormat.parse(oldDate);
        long diff = d1.getTime() - d2.getTime();
        return Math.toIntExact(diff / 1000 / 60 / 60 / 24);
    }

}
